use std::fs;
use std::str::FromStr;
use sqlx::{SqlitePool,sqlite::{SqlitePoolOptions, SqliteConnectOptions}};
use crate::get_path::get_path;
use std::sync::Arc;
use tokio::sync::OnceCell;


static DB_POOL: OnceCell<Arc<SqlitePool>> = OnceCell::const_new();

pub async fn db_init() -> Arc<SqlitePool>{
    DB_POOL
            .get_or_init(|| async {
                let db_path = get_path().join("data").join("app.db");

                if !db_path.parent().unwrap().exists() {
                    fs::create_dir_all(db_path.parent().unwrap()).unwrap();
                }
                // println!("db_path: {:?}", db_path);

                let db_url = format!("sqlite://{}", db_path.to_string_lossy());

                let connect_options = SqliteConnectOptions::from_str(&db_url)
                    .unwrap()
                    .create_if_missing(true);

                let pool = SqlitePoolOptions::new()
                    .max_connections(5)
                    .connect_with(connect_options)
                    .await
                    .expect("Failed to connect to SQLite");

                sqlx::query(
                    r#"
                    CREATE TABLE IF NOT EXISTS config (
                        key TEXT PRIMARY KEY,
                        value TEXT
                    )
                    "#,
                )
                .execute(&pool)
                .await
                .expect("Failed to create table");

                return Arc::new(pool);
            })
        .await
        .clone()
}